/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package shaman.storage.impl.local;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import shaman.storage.Factory;
import shaman.storage.StorageList;
import shaman.storage.api.Backup;
import shaman.storage.api.Filter;
import shaman.storage.api.Storage;
import shaman.storage.impl.file.FileStorage;
import shaman.storage.impl.filter.published.BufferPostprocessor;
import shaman.storage.impl.filter.published.BufferPreprocessor;
import shaman.storage.impl.filter.published.DeflateFilter;

/**
 *
 * @author dmitriy
 */
@XStreamAlias("localStorage")
public class LocalStorage extends FileStorage {

    public static final String PROPERTY_PATH="Путь";
    public static final List<String> propNames;

    static {
        List<String> names=new ArrayList<String>(FileStorage.propertyNames);
        names.add(PROPERTY_PATH);
        propNames=Collections.unmodifiableList(names);
    }

    private transient File root;

    @XStreamAlias("rootPath")
    public String rootPath;

    public LocalStorage() {
        StorageList.addFactory(new LocalStorageFactory());
    }

    @Override
    public String getTypeName() {
        return "Локальное";
    }

    public String getLocation() {
        if (root!=null)
            return root.getAbsolutePath();
        else
            return rootPath;
    }

    @Override
    public InputStream getStorageFile(String name, long offset, long length) throws IOException, FileNotFoundException {
        if (root==null)
        {
            if (rootPath!=null)
                root=new File(rootPath);
            else
                throw new IOException("Не установлена корневая папка");
        }
        root.mkdirs();
        InputStream stream=new FileInputStream(new File(root, name));
        if (offset!=0)
            stream.skip(offset);
        return stream;
    }

    @Override
    public OutputStream writeStorageFile(String name) throws IOException, FileNotFoundException {
        if (!root.exists())
            root.mkdirs();
        if (root.exists() && !root.isDirectory())
            throw new FileNotFoundException("Корень хранилища не является папкой");
        return new FileOutputStream(new File(root, name));
    }

    @Override
    public List<String> getPropertyNames() {
        return propNames;
    }

    @Override
    public String getPropertyValue(String name) throws InvalidParameterException {
        if (PROPERTY_PATH.equals(name))
        {
            if (root==null)
                return null;
            else
                return root.getAbsolutePath();
        }
        else
            return super.getPropertyValue(name);
    }

    @Override
    public List<String> getPropertyValues(String name) throws InvalidParameterException {
        if (PROPERTY_PATH.equals(name))
            return null;
        else
            return super.getPropertyValues(name);
    }

    @Override
    public void setPropertyValue(String name, String value) throws InvalidParameterException {
        if (PROPERTY_PATH.equals(name))
        {
            rootPath=value;
            root=new File(value);
        }
        else
            super.setPropertyValue(name, value);
    }

    public boolean isAccessible() {
        return true;
    }

    public static void main(String[] args) throws IOException {
        LocalStorage st=new LocalStorage();
        st.setPropertyValue(PROPERTY_PATH, "testrep");
        Backup backup=st.newBackup(Arrays.asList(new Filter[] {
            new BufferPreprocessor(),
        //    new DeflateFilter(),
            new BufferPostprocessor()
        }));
        int i;
        for (i=0; i<10; i++)
        {
            OutputStream fileStream=backup.createFile("test"+i, null);
            PrintWriter wr=new PrintWriter(fileStream);
            wr.println("Hello World! "+i);
            wr.close();
            fileStream.close();
        }
        backup.finish();
        InputStream is=backup.getFileData("test3");
        BufferedReader rd=new BufferedReader(new InputStreamReader(is));
        System.out.println(rd.readLine());
        rd.close();
        is.close();
    }
}
